#include "aeroquadmodel.h"

#include <QStringList>

AeroQuadModel::AeroQuadModel(QObject *parent) :
    BaseModel(parent)
{
    // Initialize member variables

    _deviceX = 0;
    _deviceY = 0;
    _deviceZ = 0;
    _deviceXVelocity = 0;
    _deviceYVelocity = 0;
    _deviceZVelocity = 0;

    _deviceRoll = 0;
    _devicePitch = 0;
    _deviceYaw = 0;
    _deviceRollRate = 0;
    _devicePitchRate = 0;
    _deviceYawRate = 0;

    _deviceGainsRoll[0] = 0;
    _deviceGainsRoll[1] = 0;
    _deviceGainsRoll[2] = 0;

    _deviceGainsPitch[0] = 0;
    _deviceGainsPitch[1] = 0;
    _deviceGainsPitch[2] = 0;

    _deviceGainsYaw[0] = 0;
    _deviceGainsYaw[1] = 0;
    _deviceGainsYaw[2] = 0;

    _connectionObj = new AeroQuadConnection();

    connect(_connectionObj, SIGNAL(processedDataAvailable(QString)), this, SLOT(processData(QString)));
}

AeroQuadModel::~AeroQuadModel()
{
    _connectionObj->endConnection();

    delete _connectionObj;
}

/*
  toString

  Desc - Returns a string representation of the state of the model
  */
QString AeroQuadModel::toString()
{

    QString outputString;

    outputString = QString::number(_deviceX);
    outputString += ",";
    outputString += QString::number(_deviceY);
    outputString += ",";
    outputString += QString::number(_deviceZ);
    outputString += ",";
    outputString += QString::number(_deviceXVelocity);
    outputString += ",";
    outputString += QString::number(_deviceYVelocity);
    outputString += ",";
    outputString += QString::number(_deviceZVelocity);
    outputString += ",";

    outputString += QString::number(_deviceRoll);
    outputString += ",";
    outputString += QString::number(_devicePitch);
    outputString += ",";
    outputString += QString::number(_deviceYaw);
    outputString += ",";
    outputString += QString::number(_deviceRollRate);
    outputString += ",";
    outputString += QString::number(_devicePitchRate);
    outputString += ",";
    outputString += QString::number(_deviceYawRate);
    outputString += ",";

    outputString += QString::number(_deviceGainsRoll[0]);
    outputString += ",";
    outputString += QString::number(_deviceGainsRoll[1]);
    outputString += ",";
    outputString += QString::number(_deviceGainsRoll[2]);
    outputString += ",";

    outputString += QString::number(_deviceGainsPitch[0]);
    outputString += ",";
    outputString += QString::number(_deviceGainsPitch[1]);
    outputString += ",";
    outputString += QString::number(_deviceGainsPitch[2]);
    outputString += ",";

    outputString += QString::number(_deviceGainsYaw[0]);
    outputString += ",";
    outputString += QString::number(_deviceGainsYaw[1]);
    outputString += ",";
    outputString += QString::number(_deviceGainsYaw[2]);

    return outputString;
}

/*
  toLiveLogEntry

  Desc - Returns a string representation of the state of the model
         for entry into the live log
  */
QString AeroQuadModel::toLiveLogEntry()
{

    QString outputString;

    outputString = "X:";
    outputString += QString::number(_deviceX);
    outputString += ", Y:";
    outputString += QString::number(_deviceY);
    outputString += ", Z:";
    outputString += QString::number(_deviceZ);
    outputString += ", Vx:";
    outputString += QString::number(_deviceXVelocity);
    outputString += ", Vy:";
    outputString += QString::number(_deviceYVelocity);
    outputString += ", Vz:";
    outputString += QString::number(_deviceZVelocity);

    outputString += ", R:";
    outputString += QString::number(_deviceRoll);
    outputString += ", P:";
    outputString += QString::number(_devicePitch);
    outputString += ", Y:";
    outputString += QString::number(_deviceYaw);
    outputString += ", Vr:";
    outputString += QString::number(_deviceRollRate);
    outputString += ", Vp:";
    outputString += QString::number(_devicePitchRate);
    outputString += ", Vy:";
    outputString += QString::number(_deviceYawRate);

    outputString += ", Pr:";
    outputString += QString::number(_deviceGainsRoll[0]);
    outputString += ", Ir:";
    outputString += QString::number(_deviceGainsRoll[1]);
    outputString += ", Dr:";
    outputString += QString::number(_deviceGainsRoll[2]);

    outputString += ", Pp:";
    outputString += QString::number(_deviceGainsPitch[0]);
    outputString += ", Ip:";
    outputString += QString::number(_deviceGainsPitch[1]);
    outputString += ", Dp:";
    outputString += QString::number(_deviceGainsPitch[2]);

    outputString += ", Py:";
    outputString += QString::number(_deviceGainsYaw[0]);
    outputString += ", Iy:";
    outputString += QString::number(_deviceGainsYaw[1]);
    outputString += ", Dy:";
    outputString += QString::number(_deviceGainsYaw[2]);

    return outputString;
}


/*
  toRollLiveLogEntry

  Desc - Returns a string representation of the state of the model
         for entry into the roll live log
  */
QString AeroQuadModel::toRollLiveLogEntry()
{

    QString outputString;

    outputString = "R:";
    outputString += QString::number(_deviceRoll);
    outputString += " Vr:";
    outputString += QString::number(_deviceRollRate);

    outputString += " Pr:";
    outputString += QString::number(_deviceGainsRoll[0]);
    outputString += " Ir:";
    outputString += QString::number(_deviceGainsRoll[1]);
    outputString += " Dr:";
    outputString += QString::number(_deviceGainsRoll[2]);

    return outputString;
}

/*
  toPitchLiveLogEntry

  Desc - Returns a string representation of the state of the model
         for entry into the pitch live log
  */
QString AeroQuadModel::toPitchLiveLogEntry()
{

    QString outputString;

    outputString = "P:";
    outputString += QString::number(_devicePitch);
    outputString += " Vp:";
    outputString += QString::number(_devicePitchRate);

    outputString += " Pp:";
    outputString += QString::number(_deviceGainsPitch[0]);
    outputString += " Ip:";
    outputString += QString::number(_deviceGainsPitch[1]);
    outputString += " Dp:";
    outputString += QString::number(_deviceGainsPitch[2]);

    return outputString;
}

/*
  toYawLiveLogEntry

  Desc - Returns a string representation of the state of the model
         for entry into the yaw live log
  */
QString AeroQuadModel::toYawLiveLogEntry()
{

    QString outputString;

    outputString += "Y:";
    outputString += QString::number(_deviceYaw);
    outputString += " Vy:";
    outputString += QString::number(_deviceYawRate);

    outputString += " Py:";
    outputString += QString::number(_deviceGainsYaw[0]);
    outputString += " Iy:";
    outputString += QString::number(_deviceGainsYaw[1]);
    outputString += " Dy:";
    outputString += QString::number(_deviceGainsYaw[2]);

    return outputString;
}


/*
  createConnection

  Desc - Creates a new connection object within the model
  */
void AeroQuadModel::createConnection()
{
    //TODO
}

/*
  destroyConnection

  Desc - Destroys the connection object within the model
  */
void AeroQuadModel::destroyConnection()
{
    //TODO
}

/*
  getConnection

  Desc - Returns a reference to the connection object
  */
AeroQuadConnection *AeroQuadModel::getConnection()
{
    //TODO
}

/*
  getIPAddress

  Desc - Returns the IP address of the connection within the model
  */
int *AeroQuadModel::getIPAddress()
{
    return _connectionObj->getIPAddress();
}

/*
  getRollGain

  Desc - Returns either the P, I or D value for roll
  */
int AeroQuadModel::getRollGain(GCSCommon::GainValues gainType)
{
    return _deviceGainsRoll[gainType];
}

/*
  getPitchGain

  Desc - Returns either the P, I or D value for pitch
  */
int AeroQuadModel::getPitchGain(GCSCommon::GainValues gainType)
{
    return _deviceGainsPitch[gainType];
}

/*
  getYawGain

  Desc - Returns either the P, I or D value for yaw
  */
int AeroQuadModel::getYawGain(GCSCommon::GainValues gainType)
{
    return _deviceGainsYaw[gainType];
}

/*
  getXPosition

  Desc - Returns the X position value of the Arduino
  */
float AeroQuadModel::getXPosition()
{
    return _deviceX;
}

/*
  getYPosition

  Desc - Returns the Y position value of the Arduino
  */
float AeroQuadModel::getYPosition()
{
    return _deviceY;
}

/*
  getZPosition

  Desc - Returns the Z position value of the Arduino
  */
float AeroQuadModel::getZPosition()
{
    return _deviceZ;
}

/*
  getXVelocity

  Desc - Returns the X velocity value of the Arduino
  */
float AeroQuadModel::getXVelocity()
{
    return _deviceXVelocity;
}

/*
  getYVelocity

  Desc - Returns the Y velocity value of the Arduino
  */
float AeroQuadModel::getYVelocity()
{
    return _deviceYVelocity;
}

/*
  getZVelocity

  Desc - Returns the Z velocity value of the Arduino
  */
float AeroQuadModel::getZVelocity()
{
    return _deviceZVelocity;
}

/*
  getRoll

  Desc - Returns the roll value of the Arduino
  */
int AeroQuadModel::getRoll()
{
    return _deviceRoll;
}

/*
  getPitch

  Desc - Returns the pitch value of the Arduino
  */
int AeroQuadModel::getPitch()
{
    return _devicePitch;
}

/*
  getYaw

  Desc - Returns the yaw value of the Arduino
  */
int AeroQuadModel::getYaw()
{
    return _deviceYaw;
}

/*
  getRollRate

  Desc - Returns the roll rate value of the Arduino
  */
int AeroQuadModel::getRollRate()
{
    return _deviceRollRate;
}

/*
  getPitchRate

  Desc - Returns the pitch rate value of the Arduino
  */
int AeroQuadModel::getPitchRate()
{
    return _devicePitchRate;
}

/*
  getYawRate

  Desc - Returns the yaw rate value of the Arduino
  */
int AeroQuadModel::getYawRate()
{
    return _deviceYawRate;
}


// slots

/*
  processData

  Desc - Processes a string of data
  */
void AeroQuadModel::processData(QString incomingData)
{
    // DEBUG - temp
    QStringList dataValues = incomingData.split(",");

    _deviceRoll = dataValues.at(0).toFloat();
    _devicePitch = dataValues.at(1).toFloat();
    //TODO
}

/*
  sendVICONValuesToArduino

  Desc - Sends a collection of values to the Arduino device.
         These values are x, y, z and yaw
  */
void AeroQuadModel::sendVICONValuesToArduino(QString VICONValues)
{
    //TODO
}

/*
  sendRollGainsToArduino

  Desc - Sends roll gain values from the UI to the Arduino.
         Gain values are in the order P,I,D
  */
void AeroQuadModel::sendRollGainsToArduino(int gainValues[3])
{
    //TODO
}

/*
  sendPitchGainsToArduino

  Desc - Sends pitch gain values from the UI to the Arduino.
         Gain values are in the order P,I,D
  */
void AeroQuadModel::sendPitchGainsToArduino(int gainValues[3])
{
    //TODO
}

/*
  sendYawGainsToArduino

  Desc - Sends yaw gain values from the UI to the Arduino.
         Gain values are in the order P,I,D
  */
void AeroQuadModel::sendYawGainsToArduino(int gainValues[3])
{
    //TODO
}

/*
  changeIPAddress

  Desc - Stops the connection, changes the IP address, and starts the connection
         again
  */
void AeroQuadModel::changeIPAddress(int *newIPAddress)
{

    _connectionObj->endConnection();

    _connectionObj->setIPAddress(newIPAddress);

    _connectionObj->startConnection();

    emit ipAddressHasBeenChanged();
}
